package cn.openea.perpartner.meily.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.openea.perpartner.common.core.constant.Constants;
import cn.openea.perpartner.common.core.exception.ServiceException;
import cn.openea.perpartner.common.core.utils.StringUtils;
import cn.openea.perpartner.common.redis.service.RedisCache;
import cn.openea.perpartner.meily.util.UserContext;
import cn.openea.perpartner.meily.web.entity.TaskHall;
import cn.openea.perpartner.meily.web.entity.dto.SearchDto;
import cn.openea.perpartner.meily.web.entity.vo.TaskHallVo;
import cn.openea.perpartner.meily.web.mapper.TaskHallMapper;
import cn.openea.perpartner.meily.web.service.ITaskHallService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * (MerryTaskHall)表服务实现类
 *
 * @author Weird077
 * @since 2022-12-01 18:22:44
 */
@Service
public class TaskHallServiceImpl extends ServiceImpl<TaskHallMapper, TaskHall> implements ITaskHallService {
    @Autowired
    private RedisCache redisCache;
    @Value("${meily.redis.expire.task}")
    private long expireTime;

    @Override
    public List<TaskHall> selectList(SearchDto dto) {
        LambdaQueryWrapper<TaskHall> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskHall::getTaskStatus, "上架");
        if (StrUtil.isNotBlank(dto.getCollectType())) {
            wrapper.eq(TaskHall::getCollectType, dto.getCollectType());
        }
        if (StrUtil.isNotBlank(dto.getTaskLabel())) {
            wrapper.eq(TaskHall::getTaskLabel, dto.getTaskLabel());
        }

        // 类型。评测需求(品牌推广)、样品发放(样品推广)
        if (StrUtil.isNotBlank(dto.getTaskType())) {
            wrapper.eq(TaskHall::getTaskType, dto.getTaskType());
        }

        // 关键字搜索
        if (StrUtil.isNotBlank(dto.getSearchStr())) {
            wrapper.and(wrap -> wrap.eq(TaskHall::getTaskNumber, dto.getSearchStr())
                    .or().like(TaskHall::getTaskName, dto.getSearchStr())
                    .or().like(TaskHall::getTaskDetail, dto.getSearchStr())
                    .or().like(TaskHall::getTaskPrice, dto.getSearchStr())
                    .or().like(TaskHall::getTaskType, dto.getSearchStr())
                    .or().like(TaskHall::getTaskKeyword, dto.getSearchStr())
                    .or().like(TaskHall::getTaskLabel, dto.getSearchStr())
                    .or().like(TaskHall::getCreateUserName, dto.getSearchStr()));
        }

        wrapper.orderByDesc(TaskHall::getCreateTime);

        return list(wrapper);
    }

    @Override
    public TaskHall getHotTask(SearchDto dto) {
        String key = dto.getCollectType() + ".hot.task";
        TaskHall hall = redisCache.getCacheObject(getCacheKey(key));
        if (BeanUtil.isNotEmpty(hall)) {
            return hall;
        }
        LambdaQueryWrapper<TaskHall> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskHall::getTaskStatus, "上架");
        wrapper.eq(TaskHall::getCollectType, dto.getCollectType());
        wrapper.orderByDesc(TaskHall::getCreateTime);
        wrapper.last("limit 1");
        hall = getOne(wrapper);
        if (BeanUtil.isNotEmpty(hall)) {
            redisCache.setCacheObject(getCacheKey(key), hall);
            redisCache.expire(getCacheKey(key), expireTime, TimeUnit.MINUTES);
            return hall;
        }
        return new TaskHall();
    }

    @Override
    public boolean insert(TaskHall taskHall) {
        if (StrUtil.isBlank(taskHall.getCreateUser())) {
            taskHall.setCreateUser(UserContext.getUserId());
        }
        if (StrUtil.isBlank(taskHall.getCreateUserName())) {
            taskHall.setCreateUserName(UserContext.getUserName());
        }
        if(StrUtil.isNotBlank(taskHall.getTaskStatus())){
            taskHall.setTaskStatus(taskHall.getTaskStatus());
        } else {
            taskHall.setTaskStatus("上架");
        }

        String key = taskHall.getCollectType() + ".hot.task";
        redisCache.setCacheObject(getCacheKey(key), taskHall);
        if (Boolean.TRUE.equals(redisCache.hasKey(getCacheKey("index.task")))){
            redisCache.deleteObject(getCacheKey("index.task"));
        }
        return save(taskHall);
    }

    @Override
    public boolean edit(TaskHall hall) {
        LambdaQueryWrapper<TaskHall> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskHall::getTaskCurrentId, hall.getTaskCurrentId());
        TaskHall taskHall = getOne(wrapper);
        if (BeanUtil.isEmpty(taskHall)) {
            return false;
        }
        if (StrUtil.isNotBlank(hall.getTaskState())) {
            taskHall.setTaskState(hall.getTaskState());
        }
        if (StrUtil.isNotBlank(hall.getTaskStatus())) {
            taskHall.setTaskStatus(hall.getTaskStatus());
        }
        if (StrUtil.isNotBlank(hall.getTaskHistoryId())) {
            HashSet<String> set = StringUtils.splitAsSet(hall.getTaskHistoryId());
            String historyId = StringUtils.join(set, taskHall.getTaskHistoryId());
            taskHall.setTaskHistoryId(historyId);
        }
        if (StrUtil.isNotBlank(hall.getTaskUser())) {
            HashSet<String> set = StringUtils.splitAsSet(hall.getTaskUser());
            String taskUser = StringUtils.join(set, taskHall.getTaskUser());
            taskHall.setTaskUser(taskUser);
        }
        if (StrUtil.isNotBlank(hall.getTaskAuthor())) {
            HashSet<String> set = StringUtils.splitAsSet(hall.getTaskAuthor());
            String taskAuthor = StringUtils.join(set, taskHall.getTaskAuthor());
            taskHall.setTaskAuthor(taskAuthor);
        }
        return updateById(taskHall);
    }

    @Override
    public List<TaskHall> selectIndexList(SearchDto dto) {
        List<TaskHall> taskList = redisCache.getCacheList(getCacheKey("index.task"));
        if (!taskList.isEmpty()) {
            return taskList;
        }
        LambdaQueryWrapper<TaskHall> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskHall::getTaskStatus, "上架");
        if (StrUtil.isNotBlank(dto.getCollectType())) {
            wrapper.eq(TaskHall::getCollectType, dto.getCollectType());
        }
        wrapper.orderByDesc(TaskHall::getCreateTime);
        wrapper.last("limit 5");
        taskList = list(wrapper);
        if (!taskList.isEmpty()) {
            redisCache.setCacheList(getCacheKey("index.task"), taskList);
            redisCache.expire(getCacheKey("index.task"), expireTime, TimeUnit.MINUTES);
        }
        return taskList;
    }

    /**
     * 批量下架任务
     * @param vo
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public boolean offShelf(TaskHallVo vo) {
        LambdaUpdateWrapper<TaskHall> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(TaskHall::getTaskCurrentId, vo.getCurrentIds());
        updateWrapper.set(TaskHall::getTaskState, "需求下架");
        updateWrapper.set(TaskHall::getTaskStatus, "下架");
        if(!update(updateWrapper)){
            throw new ServiceException("批量下架任务出错了！");
        }
        return true;
    }

    /**
     * 根据企业编号获取任务列表
     * @param enterpriseNo
     * @return
     */
    @Override
    public List<TaskHall> getListByEnterpriseNo(String enterpriseNo) {
        List<TaskHall> list = new ArrayList<>();
        if(StrUtil.isNotBlank(enterpriseNo)){
            list = baseMapper.getListByEnterpriseNo(enterpriseNo);
        }

        return list;
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    private String getCacheKey(String configKey) {
        return Constants.MERRY_CONFIG_KEY + configKey;
    }
}

